<?php
/**
 * наследовать можно от чего угодно, но только, чтоб поддерживало ->asXML и xpatch
 * */
class Entity extends SimpleXMLElement
{
	/**
	 * лоадит схему в класс? все в шоке
	 * с названием в виде имени класса
	 *
	 * вообще-то надо было назвать функу prepare
	 * */
	static function load($data = DEFAULT_SCHEME)	//	решили?
	{
		_log('load data',$data);
		$obj = null;

		if (_isXML($data))
			$obj = new Entity($data);

		elseif (is_readable($data))	//	вдруг это файл
		{ print 1111;
			$a = _m($data,null,true);
			_log( $a);
			_log(_isXML($a));
_log(22222);
			_log('aaaaaaaaaa',$a,_isXML($a));

			$obj = new Entity($a);
			//$obj = new Entity(_m($data,0,true));
		}
//var_dump($obj);
		if (!is_object($obj))
			return null;

		//unset($obj[0]['module']);		//	к вопросу о рутовом контексте
		//$obj->addAttribute('module',$this->__root);

		unset($obj[0]['id']);
		$obj->addAttribute('id',0);

		return $obj;
	}

	/**
	 * что-то грузит со стороннего ресурса
	 *
	 * о_О
	 *
	 * @example
	 * $sdh = new Storage();
	 * $data = $sdh->from(ext_path);
	 * or $data =& $sdh->create( $sdh->from(ext_path) );
	 *
	 * */
	public function from($external)
	{
		return Storage::load( file_get_contents($external) );
	}


	/**
	 * мерджит хмл. звезда в шоке
	 *
	 * один недостаток: плюёт на рутовые ноды. уже проде бы нет, но неймспейсы вряд ли учитывает
	 *
	 * @example NB:
	 * $x1 = '<r><b>test</b></r>';
	 * $x2 = '<r><b><d><![CDATA[TEST]]></d></b></r>';
	 * result = '<r><b>test</b></r>';
	 * */
	/*private ?? static ??*/
	static function merge(/*неопределённое количество параметров*/)
	{
		$na = func_num_args();
		if (0==$na)
			return null;
		if (1==$na)
			return (object)func_get_arg(0);

		$args = func_get_args();
		$i = 0;
		$a = array();
		$root = $args[0]->getName();	//	тупо нужен рут

//XML_OPTION_CASE_FOLDING  	integer  	 Controls whether case-folding is enabled for this XML parser. Enabled by default.
//XML_OPTION_SKIP_WHITE 	integer 	Whether to skip values consisting of whitespace characters.


		while ($i<$na)		//	можно было заюзать парсер, но мы ведь изобретаем велосипеды?
		{
			$vals = array();
			//а вот и парсер
			//$p = xml_parser_create();
			//xml_parser_set_option($p,XML_OPTION_CASE_FOLDING,0);
			//xml_parser_set_option($p,XML_OPTION_SKIP_WHITE,0);
			//xml_parse_into_struct($p, $args[$i]->asXML(), $vals/*, $index*/);
			//$a = array_merge_recursive($a, $vals);
			//$a = $vals + $a;
			//xml_parser_free($p);
//var_dump('vals!!!!!',$vals);

			$a = array_merge_recursive($a, array( $root => $args[$i] ));
			$i++;
		}

//var_dump($a);

		// теперь обратно
		function ar2xml($ar)
		{
			$xml = '';

			while ( list($key,$value) = each($ar) )
			{
				if ('@attributes' === $key)
				{
					foreach ( $value as $a_name => $a_value )
					{
						if ( is_array($a_value) )
							$xml .= ' '.$a_name.'="'.end($a_value).'"';
						elseif (is_string($a_value))
							$xml .= ' '.$a_name.'="'.$a_value.'"';
						else
							$xml .= ' '.$a_name.'=""';
					}
				}
				elseif (is_string($key))	//	nodename
				{
					if (is_object($value))
						$xml .= $value->asXML();

					elseif (is_string($value))
						$xml .= '<'.$key.'>'.$value.'</'.$key.'>';

					elseif (is_array($value))
					{
						//var_dump('---------ARRAY-VALUE---------',$key,$value);
						$xml .= '<'.$key ;
						if (array_key_exists('@attributes',$value))
						{
							$xml .= ar2xml(array('@attributes'=>$value['@attributes'])) ;
								unset($value['@attributes']);
						}
						$xml .= '>'. ar2xml($value) . '</' . $key . '>';
						//var_dump($xml);
					}
					else
						$xml .= "<{$key}/>";
				}
				else
					$xml .= htmlentities( (string) $value );	//	а можно было б и в цдату завернуть
			}
			return $xml;	//	RETURN
		}
_log('MERGE------------',var_export(f_xml($b=ar2xml($a)),true));
		return self::load( f_xml(ar2xml($a)) ) ;
	}
}

//function a2xml($a)
//{
//	$r = new stdClass;
//	foreach ($a as $k => $v)
//	{
//		if (is_array($v))
//			$r->{(string)$k} = a2xml($v);
//		else
//			$r->{(string)$k} = $v;
//	}
//	return $r;
//}
//function s2xml($s,$c=null)
//{
//	return simplexml_load_string($s,$c);
//}

?>